﻿using System;
using System.Collections.Generic;
using System.Text;
using JWFW.SFL;
using JWFW.Encrypt;
using BaseServer.BRL;

namespace BaseServer.REG
{
    public class RegCreator
    {
        //【fail：信息不对】，【expire：过期】，【servererror：服务端程序出错】，【islatest：是最新版本】

        /// <summary>
        /// 获取注册码
        /// </summary>
        /// <param name="serialNumber"></param>
        /// <param name="toolCode"></param>
        /// <param name="saleID"></param>
        /// <param name="endDate"></param>
        /// <param name="extensionInfo"></param>
        /// <returns></returns>
        public static string GetRegCode(string serialNumber, string toolCode, int saleID, DateTime endDate, string extensionInfo)
        {
            //Note:{【(软件序列号)+|+@F【工具代号】+|+@F【销售记录ID】+|+@F【最终日期Date】+|+@F【扩展信息】】} 
            string res = MD5.GetMD5_8(serialNumber) +
                CommonOP.Spliter + Base64.Encrypt(EncryptOP.RandomReverse(EncryptOP.InsertRandom(toolCode))) +
                CommonOP.Spliter + Base64.Encrypt(EncryptOP.RandomReverse(EncryptOP.InsertRandom(saleID.ToString()))) +
                CommonOP.Spliter + Base64.Encrypt(EncryptOP.RandomReverse(EncryptOP.InsertRandom(endDate.ToString("yyyy-MM-dd")))) +
                CommonOP.Spliter + Base64.Encrypt(EncryptOP.RandomReverse(EncryptOP.InsertRandom(extensionInfo)));
            return EncryptOP.RandomMultiTimesEncrypt(EncryptOP.InsertRandom(res));
        }

        /// <summary>
        /// 申请试用版
        /// </summary>
        /// <param name="serialNumber">软件的序列号</param>
        /// <param name="toolCode">工具代号</param>
        /// <returns>注册码或错误信息</returns>
        public static string TrialAccount(string serialNumber, string toolCode)
        {
            try
            {
                Trial ett = new Trial();
                ett.GetProperties(serialNumber);
                if (ett.ID == 0)
                {
                    Tool t = new Tool();
                    t.GetProperties(toolCode);
                    if (t.ID == 0)
                    {
                        throw new Exception();
                    }
                    ett.Code = serialNumber;
                    ett.ToolID = t.ID;
                    ett.EndDate = DateTime.Now.AddDays(t.TrialDay);
                    ett.SpecialInfo = "";
                    ett.RegCode = GetRegCode(serialNumber, toolCode, 0, ett.EndDate, ett.SpecialInfo);
                    ett.Add();
                }
                return GetNormalResponse(ett.RegCode);
            }
            catch
            {
                return GetErrorMsg("servererror");
            }
        }
        /// <summary>
        /// 申请试用版
        /// </summary>
        /// <param name="clientInfo">客户端提交的信息</param>
        /// <returns></returns>
        public static string TrialAccount(string clientInfo)
        {
            try
            {
                clientInfo = EncryptOP.DecryptString(clientInfo);
                string[] infos = CommonOP.SplitString(clientInfo, CommonOP.Spliter);
                return RegCreator.TrialAccount(infos[0], infos[1]);
            }
            catch
            {
                return GetErrorMsg("servererror");
            }
        }
        /// <summary>
        /// 获取最新版的下载地址
        /// </summary>
        /// <param name="clientInfo"></param>
        /// <returns></returns>
        public static string GetNewVersionUrl(string clientInfo)
        {
            string toolCode = "";
            int saleID = 0;
            DateTime endDate = DateTime.MinValue;
            string version = "";
            string extensionInfo = "";
            string validate = ValidateAccount(clientInfo, out toolCode, out saleID, out endDate, out version, out extensionInfo);
            if (validate == "")
            {
                Tool t = new Tool();
                t.GetProperties(toolCode);
                if (version != t.Version)
                {
                    return GetNormalResponse(t.DownloadLink);
                }
                else
                {
                    return GetErrorMsg("islatest");
                }
            }
            return validate;
        }
        /// <summary>
        /// 验证客户端信息
        /// </summary>
        /// <param name="clientInfo"></param>
        /// <returns></returns>
        public static string ValidateAccount(string clientInfo)
        {
            string toolCode = "";
            int saleID = 0;
            DateTime endDate = DateTime.MinValue;
            string version = "";
            string extensionInfo = "";
            return ValidateAccount(clientInfo, out toolCode, out saleID, out endDate, out version, out extensionInfo);
        }
        /// <summary>
        /// 获取运行时的信息
        /// </summary>
        /// <param name="clientInfo"></param>
        /// <returns></returns>
        public static string GetInfo(string clientInfo)
        {
            string toolCode = "";
            int saleID = 0;
            DateTime endDate = DateTime.MinValue;
            string version = "";
            string extensionInfo = "";
            string validate = ValidateAccount(clientInfo, out toolCode, out saleID, out endDate, out version, out extensionInfo);
            if (extensionInfo == "")
            {
                return GetErrorMsg("fail");
            }
            if (validate != "")
            {
                return validate;
            }

            Tool t = new Tool();
            t.GetProperties(toolCode);
            string v = t.ReflectInfos[extensionInfo];
            if (!string.IsNullOrEmpty(v))
            {
                return GetNormalResponse(v);
            }
            else
            {
                return GetErrorMsg("fail");
            }
        }

        /// <summary>
        /// 验证客户端信息
        /// </summary>
        /// <param name="clientInfo"></param>
        /// <param name="toolCode"></param>
        /// <param name="saleID"></param>
        /// <param name="endDate"></param>
        /// <param name="version"></param>
        /// <param name="extensionInfo"></param>
        /// <returns></returns>
        private static string ValidateAccount(string clientInfo, out string toolCode, out int saleID, out DateTime endDate, out string version, out string extensionInfo)
        {
            toolCode = "";
            saleID = 0;
            endDate = DateTime.MinValue;
            version = "";
            extensionInfo = "";
            string[] infos = CommonOP.SplitString(EncryptOP.RemoveInsertRandom(EncryptOP.RemoveRandomMultiRimesEncrypt(clientInfo)), CommonOP.Spliter, false);
            if (infos.Length != 4)
            {
                return GetErrorMsg("fail");
            }
            string sn = EncryptOP.DecryptString(infos[0]);
            string regCode = infos[1];//客户提交信息里面的注册码
            version = infos[2];
            extensionInfo = infos[3];//当extensionInfo为spec时，需要验证sale信息里的SpecialInfo
            string[] regCodeInfos = CommonOP.SplitString(EncryptOP.RemoveInsertRandom(EncryptOP.RemoveRandomMultiRimesEncrypt(infos[1])), CommonOP.Spliter, false);
            if (regCodeInfos.Length != 5)
            {
                return GetErrorMsg("fail");
            }
            if (MD5.GetMD5_8(sn) != regCodeInfos[0])
            {
                return GetErrorMsg("fail");
            }
            saleID = CommonOP.GetInt(EncryptOP.RemoveInsertRandom(EncryptOP.RemoveRandomReverse(Base64.Decrypt(regCodeInfos[2]))));
            if (saleID == 0)//可能是试用版
            {
                Trial t = new Trial();
                t.GetProperties(sn);
                if (t.RegCode != regCode)
                {
                    return GetErrorMsg("fail");
                }
            }
            else
            {
                Sale s = new Sale();
                s.GetProperties(saleID);
                if (s.RegCode != regCode)
                {
                    return GetErrorMsg("fail"); 
                }
            }
            endDate = DateTime.Parse(EncryptOP.RemoveInsertRandom(EncryptOP.RemoveRandomReverse(Base64.Decrypt(regCodeInfos[3]))));
            if (endDate < CommonOP.GetDate(DateTime.Now))
            {
                return GetErrorMsg("expire");
            }
            toolCode = EncryptOP.RemoveInsertRandom(EncryptOP.RemoveRandomReverse(Base64.Decrypt(regCodeInfos[1])));
            return "";
        }

        /// <summary>
        /// 获取正常的返回值：反射数据或者试用注册码或者新版下载地址
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private static string GetNormalResponse(string info)
        {
            return EncryptOP.RandomMultiTimesEncrypt(EncryptOP.RandomReverse(EncryptOP.InsertRandom(
                EncryptOP.RandomReverse(EncryptOP.InsertRandom(info)))));
        }
        /// <summary>
        /// 获取指令
        /// </summary>
        /// <param name="cmd"></param>
        /// <returns></returns>
        private static string GetCommand(string cmd)
        {
            return EncryptOP.RandomMultiTimesEncrypt(CommonOP.Spliter + EncryptOP.RemoveInsertRandom(cmd));
        }
        /// <summary>
        /// 获取错误消息
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        private static string GetErrorMsg(string msg)
        {
            return EncryptOP.RandomMultiTimesEncrypt(CommonOP.Spliter + CommonOP.Spliter + msg);
        }


        private RegCreator() { }
        private void Test()
        {
            Tool t = new Tool();
            JWFW.BOL.BaseEntity.ConnStr = "server=localhost;uid=sa;password=password123$;database=jwgf";


            string a = "fc2aYTFmYWVjNWNZaVE0T0RjMFF6RkZRMFE0UkRFME56ZEVSVFV2xKxUZXN01";
            a = TrialAccount(a);
            Console.WriteLine(a);
            Trial tr = new Trial();
            tr.GetProperties(2);
            Console.WriteLine(tr.EndDate);
        }

        private void CreateTestData()
        {
            string ConnStr = "server=localhost;uid=sa;password=password123$;database=jwgf";
            Tool t = new Tool();
            t.DB = JWFW.DAL.DBFactory.GetDBOP(ConnStr, JWFW.DAL.EDBType.SimpleSQL);
            t.Name = "测试工具";
            t.Code = "Test";
            t.Version = "1.0";
            t.DownloadLink = "http://baidu.com";
            t.ReflectInfo = "ref1=VGVzdAvv";
            t.TrialDay = 3;
            t.Price = 20;
            t.SpecialInfoName = "";
        }
    }
}
